﻿using PengSW.NotifyPropertyChanged;
using System;
using System.Data.SqlClient;
using System.Xml.Linq;
using static PengSW.XmlHelper.XmlLinqHelper;

namespace PengSW.SqlServerTools
{
    [Serializable]
    public class LoginContent : NotifyPropertyChangedObject
    {
        public LoginContent(string aDataSource, string aInitialCatalog, bool aIntegratedSecurity, string aUserId, string aPassword)
        {
            DataSource = aDataSource;
            InitialCatalog = aInitialCatalog;
            IntegratedSecurity = aIntegratedSecurity;
            UserId = aUserId;
            Password = aPassword;
        }

        public LoginContent(XElement aXElement)
        {
            ReadFromXml(aXElement);
        }

        public LoginContent Clone()
        {
            return MemberwiseClone() as LoginContent;
        }

        public string DataSource
        {
            get { return m_DataSource; }
            set { if (m_DataSource != value && value != null) { m_DataSource = value; OnPropertyChanged(nameof(DataSource)); } }
        }
        private string m_DataSource = "(local)";

        public string InitialCatalog
        {
            get { return m_InitialCatalog; }
            set { if (m_InitialCatalog != value && value != null) { m_InitialCatalog = value; OnPropertyChanged(nameof(InitialCatalog)); } }
        }
        private string m_InitialCatalog = "DatabaseName";

        public bool IntegratedSecurity
        {
            get { return m_IntegratedSecurity; }
            set { if (m_IntegratedSecurity != value) { m_IntegratedSecurity = value; OnPropertyChanged(nameof(IntegratedSecurity)); } }
        }
        private bool m_IntegratedSecurity = true;

        public string UserId
        {
            get { return m_UserId; }
            set { if (m_UserId != value) { m_UserId = value; OnPropertyChanged(nameof(UserId)); } }
        }
        private string m_UserId = "sa";

        /// <summary>
        /// Password的加密序列化
        ///     当Password发生变化时，同时更新Password的密文。
        ///     在序列化时，该密文被序列化，而Password不被序列化。
        ///     在get Password时，如果该密文存在，而Password不存在，则从密文中恢复Password
        /// </summary>
        private const string KEY_64 = "LConKey6";
        private const string IV_64 = "LoCoIv64";

        public string Password
        {
            get 
            {
                return Crypt.Crypt.Decode(m_EncodedPassword, KEY_64, IV_64);
            }
            set 
            { 
                m_EncodedPassword = Crypt.Crypt.Encode(value, KEY_64, IV_64);
                OnPropertyChanged(nameof(Password)); 
            }
        }
        private string m_EncodedPassword = null;

        public bool SavePassword
        {
            get { return m_SavePassword; }
            set 
            { 
                if (m_SavePassword != value) 
                { 
                    m_SavePassword = value; 
                    OnPropertyChanged(nameof(SavePassword));
                } 
            }
        }
        private bool m_SavePassword = true;

        public bool IsValid
        {
            get 
            { 
                if (string.IsNullOrWhiteSpace(DataSource)) return false;
                if (string.IsNullOrWhiteSpace(InitialCatalog)) return false;
                if (!IntegratedSecurity && string.IsNullOrWhiteSpace(UserId)) return false;
                return true;
            }
        }

        public string ConnectionString
        {
            get
            {
                SqlConnectionStringBuilder aSqlConnectionStringBuilder = new SqlConnectionStringBuilder();
                if (!string.IsNullOrWhiteSpace(DataSource)) aSqlConnectionStringBuilder.DataSource = DataSource;
                if (!string.IsNullOrWhiteSpace(InitialCatalog)) aSqlConnectionStringBuilder.InitialCatalog = InitialCatalog;
                aSqlConnectionStringBuilder.IntegratedSecurity = IntegratedSecurity;
                if (!string.IsNullOrWhiteSpace(UserId)) aSqlConnectionStringBuilder.UserID = UserId;
                if (!string.IsNullOrWhiteSpace(Password)) aSqlConnectionStringBuilder.Password = Password;
                
                return aSqlConnectionStringBuilder.ConnectionString;
            }
        }

        public XElement CreateXElement(string aXmlNodeName)
        {
            return new XElement(aXmlNodeName,
                CreateXAttribute(nameof(DataSource), DataSource),
                CreateXAttribute(nameof(InitialCatalog), InitialCatalog),
                CreateXAttribute(nameof(IntegratedSecurity), IntegratedSecurity),
                CreateXAttribute(nameof(UserId), UserId),
                CreateXAttribute(nameof(SavePassword), SavePassword),
                CreateXAttribute(nameof(Password), m_EncodedPassword)
            );
        }

        public void ReadFromXml(XElement aXElement)
        {
            if (aXElement == null) return;
            DataSource = aXElement.GetAttributeValue(nameof(DataSource), "localhost");
            InitialCatalog = aXElement.GetAttributeValue(nameof(InitialCatalog), "SocialMedia");
            IntegratedSecurity = aXElement.GetAttributeValue(nameof(IntegratedSecurity), true);
            UserId = aXElement.GetAttributeValue(nameof(UserId), "sa");
            m_EncodedPassword = aXElement.GetAttributeValue(nameof(Password), null);
            SavePassword = aXElement.GetAttributeValue(nameof(SavePassword), false);
        }
    }
}
